package net.adetech.dcweb.core.dc.service.impl;

import com.alibaba.fastjson.JSONObject;
import net.adetech.dcweb.core.common.entity.CommonAdminuser;
import net.adetech.dcweb.core.dc.entity.DcInfoPinyinComparator;
import net.adetech.dcweb.core.dc.entity.DcAuditComment;
import net.adetech.dcweb.core.dc.entity.DcInfo;
import net.adetech.dcweb.core.dc.service.IDcAuditCommentService;
import net.adetech.dcweb.core.dc.service.IDcInfoService;
import net.adetech.dcweb.core.ddpush.utils.IDDPushService;
import net.adetech.utils.condition.ConditionEntity;
import net.adetech.utils.condition.ConditionTools;
import net.adetech.utils.condition.SQLEntity;
import net.adetech.utils.spring.PageBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.*;

/**
 * Created by sunfeihu on 2016/10/20.
 */
@Service
public class DcInfoServiceImpl implements IDcInfoService {

    private final Logger logger = LoggerFactory.getLogger(DcInfoServiceImpl.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private IDcAuditCommentService iDcAuditCommentService;

    @Autowired
    private IDDPushService iddPushService;
    @Override
    public DcInfo save(DcInfo entity) {
        final String sql = " insert into dc_info (uuid,add_user,add_date,add_ip,add_info,update_user,update_ip,update_date,update_info,is_delete,card_no,real_name,state,create_user_id,commit_audit_date,current_audit,remark,alarm_ids,card_type,man_type,scope_type,involved_type,level_type,sex,job,leader_type) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        KeyHolder keyHolder = new GeneratedKeyHolder();
        final DcInfo finalEntity = entity;
        jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement ps = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
                ps.setObject(1, finalEntity.getUuid());
                ps.setObject(2, finalEntity.getAddUser());
                if (null != finalEntity.getAddDate()) {
                    ps.setObject(3, new java.sql.Timestamp(finalEntity.getAddDate().getTime()));
                } else {
                    ps.setObject(3, null);
                }
                ps.setObject(4, finalEntity.getAddIp());
                ps.setObject(5, finalEntity.getAddInfo());
                ps.setObject(6, finalEntity.getUpdateUser());
                ps.setObject(7, finalEntity.getUpdateIp());
                if (null != finalEntity.getUpdateDate()) {
                    ps.setObject(8, new java.sql.Timestamp(finalEntity.getUpdateDate().getTime()));
                } else {
                    ps.setObject(8, null);
                }
                ps.setObject(9, finalEntity.getUpdateInfo());
                ps.setObject(10, finalEntity.getIsDelete());
                ps.setObject(11, finalEntity.getCardNo());
                ps.setObject(12, finalEntity.getRealName());
                ps.setObject(13, finalEntity.getState());
                ps.setObject(14, finalEntity.getCreateUserId());
                if (null != finalEntity.getCommitAuditDate()) {
                    ps.setObject(15, new java.sql.Timestamp(finalEntity.getCommitAuditDate().getTime()));
                } else {
                    ps.setObject(15, null);
                }
                ps.setObject(16, finalEntity.getCurrentAudit());
                ps.setObject(17, finalEntity.getRemark());
                ps.setObject(18, finalEntity.getAlarmIds());
                ps.setObject(19, finalEntity.getCardType());
                ps.setObject(20, finalEntity.getManType());
                ps.setObject(21, finalEntity.getScopeType());
                ps.setObject(22, finalEntity.getInvolvedType());
                ps.setObject(23, finalEntity.getLevelType());
                ps.setObject(24, finalEntity.getSex());
                ps.setObject(25, finalEntity.getJob());
                ps.setObject(26, finalEntity.getLeaderType());
                return ps;
            }
        }, keyHolder);
        Long id = keyHolder.getKey().longValue();
        return this.find(id);
    }
    @Override
    public int delete(Long id) {
        final String sql = " update dc_info set is_delete = 1 where id = ? ";
        return jdbcTemplate.update(sql, new Object[]{
                id
        });
    }

    @Override
    public int update(DcInfo entity) {
        final String sql = " update dc_info set add_info=?,update_info=?,card_no=?,real_name=?,state=?,create_user_id=?,commit_audit_date=?,current_audit=?,remark=?,alarm_ids=?,card_type=?,man_type=?,scope_type=?,involved_type=?,level_type=?,sex=?,job=?,leader_type=? where id = ?";
        return jdbcTemplate.update(sql, new Object[]{
                entity.getAddInfo(),
                entity.getUpdateInfo(),
                entity.getCardNo(),
                entity.getRealName(),
                entity.getState(),
                entity.getCreateUserId(),
                entity.getCommitAuditDate(),
                entity.getCurrentAudit(),
                entity.getRemark(),
                entity.getAlarmIds(),
                entity.getCardType(),
                entity.getManType(),
                entity.getScopeType(),
                entity.getInvolvedType(),
                entity.getLevelType(),
                entity.getSex(),
                entity.getJob(),
                entity.getLeaderType(),
                entity.getId()
        });
    }

    @Override
    public DcInfo find(Long id) {
//        final String sql = " select * from dc_info where id = ? and is_delete = 0 ";
        final String sql = "select * ,(select photo from dc_people p where p.card_no= d.card_no) as photo from dc_info d where d.id = ? and d.is_delete = 0";

        try {
            return jdbcTemplate.queryForObject(sql, new Object[]{id}, new DcInfoRowerMapper());
        } catch (DataAccessException e) {
            return null;
        }
    }

    @Override
    public void save(List<DcInfo> list) {
        if (null != list && list.size() > 0) {
            final String sql = " insert into dc_info (uuid,add_user,add_date,add_ip,add_info,update_user,update_ip,update_date,update_info,is_delete,card_no,real_name,state,create_user_id,commit_audit_date,current_audit,remark,alarm_ids,card_type,man_type,scope_type,involved_type,level_type,sex,job,leader_type) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
            List
                    <Object[]> params = new ArrayList
                    <Object[]>();
            Object[] objArr = null;
            DcInfo entity = null;
            for (int i = 0; i < list.size(); i++) {
                entity = list.get(i);
                objArr = new Object[26];
                objArr[0] = entity.getUuid();
                objArr[1] = entity.getAddUser();
                objArr[2] = entity.getAddDate();
                objArr[3] = entity.getAddIp();
                objArr[4] = entity.getAddInfo();
                objArr[5] = entity.getUpdateUser();
                objArr[6] = entity.getUpdateIp();
                objArr[7] = entity.getUpdateDate();
                objArr[8] = entity.getUpdateInfo();
                objArr[9] = entity.getIsDelete();
                objArr[10] = entity.getCardNo();
                objArr[11] = entity.getRealName();
                objArr[12] = entity.getState();
                objArr[13] = entity.getCreateUserId();
                objArr[14] = entity.getCommitAuditDate();
                objArr[15] = entity.getCurrentAudit();
                objArr[16] = entity.getRemark();
                objArr[17] = entity.getAlarmIds();
                objArr[18] = entity.getCardType();
                objArr[19] = entity.getManType();
                objArr[20] = entity.getScopeType();
                objArr[21] = entity.getInvolvedType();
                objArr[22] = entity.getLevelType();
                objArr[23] = entity.getSex();
                objArr[24] = entity.getJob();
                objArr[25] = entity.getLeaderType();
                params.add(objArr);
            }
            jdbcTemplate.batchUpdate(sql, params);
        }
    }


    @Override
    public void delete(List
                               <Long> ids) {
        if (null != ids && ids.size() > 0) {
            final String sql = " update dc_info set is_delete = 1 where id = ? ";
            List
                    <Object
                            []> params = new ArrayList
                    <Object
                            []>();
            Object[] objArr = null;
            for (int i = 0; i < ids.size(); i++) {
                objArr = new Object[1];
                objArr[0] = ids.get(i);
                params.add(objArr);
            }
            jdbcTemplate.batchUpdate(sql, params);
        }
    }

    @Override
    public void update(List<DcInfo> list) {
        if (null != list && list.size() > 0) {
            final String sql = " update dc_info set add_info=?,update_info=?,card_no=?,real_name=?,state=?,create_user_id=?,commit_audit_date=?,current_audit=?,remark=?,alarm_ids=?,card_type=?,man_type=?,scope_type=?,involved_type=?,level_type=?,sex=?,job=?,leader_type=? where id = ?";
            List
                    <Object
                            []> params = new ArrayList
                    <Object
                            []>();
            Object[] objArr = null;
            DcInfo entity = null;
            for (int i = 0; i < list.size(); i++) {
                entity = list.get(i);
                objArr = new Object[18];
                objArr[0] = entity.getAddInfo();
                objArr[1] = entity.getUpdateInfo();
                objArr[2] = entity.getCardNo();
                objArr[3] = entity.getRealName();
                objArr[4] = entity.getState();
                objArr[5] = entity.getCreateUserId();
                objArr[6] = entity.getCommitAuditDate();
                objArr[7] = entity.getCurrentAudit();
                objArr[8] = entity.getRemark();
                objArr[9] = entity.getAlarmIds();
                objArr[10] = entity.getCardType();
                objArr[11] = entity.getManType();
                objArr[12] = entity.getScopeType();
                objArr[13] = entity.getInvolvedType();
                objArr[14] = entity.getLevelType();
                objArr[15] = entity.getSex();
                objArr[16] = entity.getJob();
                objArr[17] = entity.getLeaderType();
                objArr[18] = entity.getId();
                params.add(objArr);
            }
            jdbcTemplate.batchUpdate(sql, params);
        }
    }



    @Override
    public List<DcInfo> list(Integer state, CommonAdminuser adminuser) {
        if (state == 0) {
            final String sql = " select a.*,b.audit_type,b.content as audit_content,b.remark as audit_remark from dc_info a left join dc_audit_comment b on a.current_audit = b.id where a.is_delete = 0 and a.state = ? and create_user_id = ? order by a.id desc ";
            List<DcInfo> dcInfoList = jdbcTemplate.query(sql, new Object[]{state, adminuser.getId()}, new DcInfoRowerMapper());
            Collections.sort(dcInfoList,new DcInfoPinyinComparator());
            return dcInfoList;
        } else {
            final String sql = " select a.*,b.audit_type,b.content as audit_content,b.remark as audit_remark from dc_info a left join dc_audit_comment b on a.current_audit = b.id where a.is_delete = 0 and a.state = ? order by a.id desc ";
//            final String sql = "select a.*,b.audit_type,b.content as audit_content,b.remark as audit_remark ,p.photo from (dc_info a left join dc_audit_comment b on a.current_audit = b.id) LEFT JOIN dc_people p on a.card_no=p.card_no where a.is_delete = 0 and a.state = ?   order by a.id desc ";
            List<DcInfo> dcInfoList = jdbcTemplate.query(sql, new Object[]{state}, new DcInfoRowerMapper());
            Collections.sort(dcInfoList,new DcInfoPinyinComparator());
            return dcInfoList;

        }

    }

    @Override
    public void close(Long id, DcAuditComment dcAuditComment) {
        DcInfo entity = this.find(id);
        entity.setState(0);
        dcAuditComment.setAuditType(0);
        dcAuditComment = iDcAuditCommentService.save(dcAuditComment);
        entity.setCurrentAudit(dcAuditComment.getId());
        this.update(entity);
        JSONObject info = new JSONObject();
        info.put("audit_type","close");
        iddPushService.push(entity.getCreateUserId()+"","审核信息","您有一条信息["+entity.getRealName()+"]被直接取消审核",info);
    }

    @Override
    public void unpass(Long id, DcAuditComment dcAuditComment) {
        DcInfo entity = this.find(id);
        if (null != entity.getCurrentAudit() && entity.getCurrentAudit() > 0L) {
            DcAuditComment currentDcAuditComment = iDcAuditCommentService.find(entity.getCurrentAudit());
            String content = "";
            //如果是取消布控
            if (currentDcAuditComment.getAuditType().equals(0)) {
                entity.setState(2);
                dcAuditComment.setAuditType(0);
                content = "您有一条取消布控信息["+entity.getRealName()+"]未能通过审核";
            } else {//如果是开启布控
                entity.setState(0);
                dcAuditComment.setAuditType(1);
                content = "您有一条添加布控信息["+entity.getRealName()+"]未能通过审核";
            }
            dcAuditComment = iDcAuditCommentService.save(dcAuditComment);
            entity.setCurrentAudit(dcAuditComment.getId());
            this.update(entity);
            JSONObject info = new JSONObject();
            info.put("audit_type","unpass");
            iddPushService.push(entity.getCreateUserId()+"","审核信息",content,info);
        }
    }

    @Override
    public void pass(Long id, DcAuditComment dcAuditComment) {
        DcInfo entity = this.find(id);
        //如果不是待审核的数据，return
        if (!entity.getState().equals(1)) {
            return;
        }
        if (null != entity.getCurrentAudit() && entity.getCurrentAudit() > 0L) {
            DcAuditComment currentDcAuditComment = iDcAuditCommentService.find(entity.getCurrentAudit());
            String content = "";
            //如果是取消布控
            if (currentDcAuditComment.getAuditType().equals(0)) {
                entity.setState(0);
                dcAuditComment.setContent("通过取消布控");
                content = "您有一条通过取消布控信息[" + entity.getRealName() + "]通过了审核";
            } else if (currentDcAuditComment.getAuditType().equals(1)) {
                entity.setState(2);
                dcAuditComment.setContent("通过添加布控");
                content = "您有一条通过添加布控信息[" + entity.getRealName() + "]通过了审核";
            } else {
                return;
            }
            dcAuditComment = iDcAuditCommentService.save(dcAuditComment);
            entity.setCurrentAudit(dcAuditComment.getId());
            this.update(entity);
            JSONObject info = new JSONObject();
            info.put("audit_type", "pass");
            iddPushService.push( entity.getCreateUserId() + "", "审批通过信息", content, info);
        }
    }

    @Override
    public void commit(Long id) {
        final String sql = " update dc_info set state = 2 where id = ? ";
        jdbcTemplate.update(sql, new Object[]{id});
    }

    @Override
    public void audit(Long id, DcAuditComment dcAuditComment) {
        DcInfo entity = this.find(id);
        dcAuditComment = iDcAuditCommentService.save(dcAuditComment);
        final String sql = " update dc_info set commit_audit_date = ? , current_audit = ? , state = 1  where id = ? ";
        jdbcTemplate.update(sql, new Object[]{
                Calendar.getInstance().getTime(), dcAuditComment.getId(), id
        });
        JSONObject pushInfo = new JSONObject();
        pushInfo.put("audit_type", "audit");
        pushInfo.put("auditCommentId", dcAuditComment.getId());
        iddPushService.push( dcAuditComment.getAuditer() + "", "审核信息", "您有一条信息[" + entity.getRealName() + "]需要审核", pushInfo);
    }

    @Override
    public List<DcInfo> getDcInfoListByState(String state) {
        final String sql = "select * from dc_info where state = ?";
        return jdbcTemplate.query(sql, new Object[]{state}, new DcInfoRowerMapper());
    }
}


class DcInfoRowerMapper implements RowMapper<DcInfo> {
    @Override
    public DcInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        Set
                <String> fieldSet = new HashSet
                <String>();
        for (int i = 1; i <= columnCount; i++) {
            fieldSet.add(rsmd.getColumnLabel(i));
        }
        DcInfo entity = new DcInfo();
        if (fieldSet.contains("add_date") && null !=
                rs.getObject("add_date")) {
            entity.setAddDate(new
                    java.util.Date(rs.getTimestamp("add_date").getTime()));
        }
        if (fieldSet.contains("real_name") && null !=
                rs.getObject("real_name")) {
            entity.setRealName(rs.getString
                    ("real_name"));
        }
        if (fieldSet.contains("remark") && null !=
                rs.getObject("remark")) {
            entity.setRemark(rs.getString
                    ("remark"));
        }
        if (fieldSet.contains("update_ip") && null !=
                rs.getObject("update_ip")) {
            entity.setUpdateIp(rs.getString
                    ("update_ip"));
        }
        if (fieldSet.contains("uuid") && null !=
                rs.getObject("uuid")) {
            entity.setUuid(rs.getString
                    ("uuid"));
        }
        if (fieldSet.contains("level_type") && null !=
                rs.getObject("level_type")) {
            entity.setLevelType(rs.getInt
                    ("level_type"));
        }
        if (fieldSet.contains("update_user") && null !=
                rs.getObject("update_user")) {
            entity.setUpdateUser(rs.getString
                    ("update_user"));
        }
        if (fieldSet.contains("card_no") && null !=
                rs.getObject("card_no")) {
            entity.setCardNo(rs.getString
                    ("card_no"));
        }
        if (fieldSet.contains("alarm_ids") && null !=
                rs.getObject("alarm_ids")) {
            entity.setAlarmIds(rs.getString
                    ("alarm_ids"));
        }
        if (fieldSet.contains("leader_type") && null !=
                rs.getObject("leader_type")) {
            entity.setLeaderType(rs.getBoolean
                    ("leader_type"));
        }
        if (fieldSet.contains("commit_audit_date") && null !=
                rs.getObject("commit_audit_date")) {
            entity.setCommitAuditDate(new
                    java.util.Date(rs.getTimestamp("commit_audit_date").getTime()));
        }
        if (fieldSet.contains("id") && null !=
                rs.getObject("id")) {
            entity.setId(rs.getLong
                    ("id"));
        }
        if (fieldSet.contains("state") && null !=
                rs.getObject("state")) {
            entity.setState(rs.getInt
                    ("state"));
        }
        if (fieldSet.contains("involved_type") && null !=
                rs.getObject("involved_type")) {
            entity.setInvolvedType(rs.getBoolean
                    ("involved_type"));
        }
        if (fieldSet.contains("add_info") && null !=
                rs.getObject("add_info")) {
            entity.setAddInfo(rs.getString
                    ("add_info"));
        }
        if (fieldSet.contains("scope_type") && null !=
                rs.getObject("scope_type")) {
            entity.setScopeType(rs.getInt
                    ("scope_type"));
        }
        if (fieldSet.contains("create_user_id") && null !=
                rs.getObject("create_user_id")) {
            entity.setCreateUserId(rs.getLong
                    ("create_user_id"));
        }
        if (fieldSet.contains("sex") && null !=
                rs.getObject("sex")) {
            entity.setSex(rs.getBoolean
                    ("sex"));
        }
        if (fieldSet.contains("update_info") && null !=
                rs.getObject("update_info")) {
            entity.setUpdateInfo(rs.getString
                    ("update_info"));
        }
        if (fieldSet.contains("card_type") && null !=
                rs.getObject("card_type")) {
            entity.setCardType(rs.getString
                    ("card_type"));
        }
        if (fieldSet.contains("update_date") && null !=
                rs.getObject("update_date")) {
            entity.setUpdateDate(new
                    java.util.Date(rs.getTimestamp("update_date").getTime()));
        }
        if (fieldSet.contains("is_delete") && null !=
                rs.getObject("is_delete")) {
            entity.setIsDelete(rs.getBoolean
                    ("is_delete"));
        }
        if (fieldSet.contains("current_audit") && null !=
                rs.getObject("current_audit")) {
            entity.setCurrentAudit(rs.getLong
                    ("current_audit"));
        }
        if (fieldSet.contains("add_ip") && null !=
                rs.getObject("add_ip")) {
            entity.setAddIp(rs.getString
                    ("add_ip"));
        }
        if (fieldSet.contains("job") && null !=
                rs.getObject("job")) {
            entity.setJob(rs.getString
                    ("job"));
        }
        if (fieldSet.contains("man_type") && null !=
                rs.getObject("man_type")) {
            entity.setManType(rs.getInt
                    ("man_type"));
        }
        if (fieldSet.contains("add_user") && null !=
                rs.getObject("add_user")) {
            entity.setAddUser(rs.getString
                    ("add_user"));
        }
        if (fieldSet.contains("photo") && null !=
                rs.getObject("photo")) {
            entity.setPhoto(rs.getString
                    ("photo"));
        }
        return entity;
    }
}